package com.yundasys.lab02springbootstudy.propertyaccessor;

import com.alibaba.fastjson.JSON;
import net.minidev.json.JSONUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.ConfigurablePropertyAccessor;
import org.springframework.beans.NullValueInNestedPathException;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.Console;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @Title: PropertyAccessorTest
 * @Description:
 * @author: jiangta
 * @date: 2024/7/2 9:40 上午
 * @Version: 1.0
 */
@SpringBootTest
public class PropertyAccessorTest {

    @Test
    public void bean_wrapper_tests() throws Exception {
        // 1. 创建对象
        Student lee = new Student();

        // 2. 创建BeanWrapper
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(lee);

        // 3. 赋值 firstName
        beanWrapper.setPropertyValue("firstName", "Bruce");

        // 4.验证: firstName 和 name 都有值
        assertEquals("Bruce", lee.firstName);
        assertEquals("Bruce", lee.name);

        // 5. 赋值lastName
        beanWrapper.setPropertyValue("lastName", "Lee");

        // 6. 验证: lastName 和 name 都有值
        assertEquals("Lee", lee.lastName);
        assertEquals("BruceLee", lee.name);

        // 7. 默认情况下, 是不允许使用嵌套属性赋值的
        assertThrows(NullValueInNestedPathException.class, () -> beanWrapper.setPropertyValue("girlFriend.firstName", "Linda"));

        // 8. 开启允许嵌套属性赋值
        beanWrapper.setAutoGrowNestedPaths(true);

        // 9. 给girlFriend赋值
        beanWrapper.setPropertyValue("girlFriend.firstName", "Linda");
        beanWrapper.setPropertyValue("girlFriend.lastName", "Emery");

        // 10. 验证: girlFriend有值, 且girlFriend.name有值
        assertNotNull(lee.girlFriend);
        assertEquals("LindaEmery", lee.girlFriend.name);

        // 11. 通过下标访问, 给friends:List 赋值
        beanWrapper.setPropertyValue("friends[0].name", "Bar");
        beanWrapper.setPropertyValue("friends[4].name", "Foo");

        // 12.1 验证: frientds的长度为5
        assertEquals(5, lee.friends.size());

        // 12.1 验证: friends[0].name
        assertEquals("Bar", lee.friends.get(0).name);

        // 12.3 验证: 跳过的3个索引都有值, 但是只是一个空对象
        for (int i = 1; i < 4; i++) {
            assertNotNull(lee.friends.get(i));
        }

        // 12.4 验证: friends[4].name
        assertEquals("Foo", lee.friends.get(4).name);

        // 13. 嵌套属性赋值
        beanWrapper.setPropertyValue("friends[0].friends[0].name", "Bar's friend");

        // 14. 验证
        assertEquals("Bar's friend", lee.getFriends().get(0).getFriends().get(0).name);

        // 15. 以json的格式打印对象
        System.out.println(JSON.toJSONString(lee));
    }

    @Test
    public void direct_field_tests() throws Exception {
        // 1. 创建对象
        Student lee = new Student();

        // 2. 创建DirectFieldAccessor
        ConfigurablePropertyAccessor accessor = PropertyAccessorFactory.forDirectFieldAccess(lee);

        // 3. 赋值firstName
        accessor.setPropertyValue("firstName", "Bruce");
        // 3.1 验证: firstName有值
        assertEquals("Bruce", lee.firstName);
        // 3.2 验证: name为null
        assertNull(lee.name);

        // 4. 赋值lastName
        accessor.setPropertyValue("lastName", "Lee");
        // 4.1 验证: lastName有值
        assertEquals("Lee", lee.lastName);
        // 4.2 验证: name为null
        assertNull(lee.name);

        // 5. 以json的格式打印对象
        System.out.println(JSON.toJSONString(lee));
    }

}